/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package common;

import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

public class UserRPCClient {

	private RPCServiceClient serviceClient;
	private Options options;
	private EndpointReference targetEPR;
	private boolean up;
	private String wsURI;

	/**
	 * Initiate a web service client
	 * @param uri - example: "http://localhost:8080/axis2/services/CertAuthService"
	 * @throws AxisFault
	 */
	public UserRPCClient(String uri){
		this.wsURI = uri;
		connect();
	}

	/**
	 * Make a method call to the web service. 
	 * Basically our calling mechanism for remote WS methods. 
	 * @param returnType - the class type of the methods return value
	 * @param namespaceURI - web service namespace
	 * @param methodName - the method you wish to call
	 * @param mArgs - arguments for the method (if any)
	 * @return - make sure to cast to param:returnType. CAN BE NULL.
	 */
	public Object[] wsCall(Class[] returnTypes, String namespaceURI, String methodName, Object[] mArgs){
		Object[] opArgs;
		QName op;
		Object[] response = null;

		if (!this.up){
			connect();
		}
		if (this.up){
			op = new QName(namespaceURI, methodName);
			if (mArgs == null)
				opArgs = new Object[] { };
			else
				opArgs = mArgs;
			options.setAction("urn:" + methodName);
			try{
				response = serviceClient.invokeBlocking(op,
						opArgs, returnTypes);
			}
			catch (AxisFault af){
				System.out.println(af.getMessage());
				af.printStackTrace();
			}
		}
		return response;
	}


	private void connect(){
		try{
			up = true;
			this.serviceClient = new RPCServiceClient();
			this.options = serviceClient.getOptions();
			this.targetEPR = new EndpointReference(this.wsURI);
			options.setTo(targetEPR);
		}
		catch (AxisFault axisExp){
			up = false;
			//System.out.println(axisExp.getMessage());
			//axisExp.printStackTrace();
		}
	}

	public static void main(String[] args1) throws AxisFault {
		/***
    	byte[] result;

    	UserRPCClient wsClient = new UserRPCClient("http://localhost:8080/axis2/services/CertAuthService");


    	result = (byte[])wsClient.wsCall(new Class[]{byte[].class}, "http://ca.service", "getPublicKeyEncoding", (Object[])null)[0];


        SignatureVerifier sv = new SignatureVerifier(result);
		String strToSign1 = "123";
		String strToSign2 = "1234";
		byte[] byteArrToSign1 = strToSign1.getBytes();
		byte[] byteArrToSign2 = strToSign2.getBytes();
		try{
			result = (byte[])wsClient.wsCall(new Class[]{byte[].class}, "http://ca.service", "sign", new Object[]{byteArrToSign1})[0];  
	        byte[] realSig = result;

			System.out.println("signature verifies: " + sv.verify(byteArrToSign2, realSig));
			System.out.println("signature verifies: " + sv.verify(byteArrToSign1, realSig));
			System.out.println("signature verifies: " + sv.verify(byteArrToSign2, realSig));


		} catch (Exception e) {
			System.err.println("Caught exception " + e.toString());
			e.printStackTrace();
		}

		 ***/
	}
}
